package com.onpositive.notes.services;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.onpositive.collections.BasicCollection;
import com.onpositive.collections.BasicCollectionMember;
import com.onpositive.collections.CollectionsContainer;
import com.onpositive.collections.CounterValueCalculator;
import com.onpositive.collections.IMemberValueCalculator;
import com.onpositive.collections.IObjectCollection;
import com.onpositive.collections.LastValueCalculator;

public class BasicCollectionRegistry implements ICollectionRegistry {

	private static final long serialVersionUID = 2234424871964202164L;

	public static final String COLLECTION_NAME_GENERAL_TODO = "general-todo";
	
	
	public static final String COLLECTION_NAME_SIMPLE_TODO = "simple-todo";
	
	public static final String COLLECTION_NAME_GENERAL_STORAGE = "general-storage";

	public static final String COLLECTION_NAME_MONEY_COUNTER = "money-counter";

	public static final String COLLECTION_NAME_FINANCIAL_RELATIONS = "financial-relations";
	
	public static final String COLLECTION_NAME_GENERAL_STORAGE_TODO = "general-storage-todo";

	public static final String COLLECTION_NAME_MONEY_COUNTER_TODO = "money-counter-todo";

	public static final String COLLECTION_NAME_FINANCIAL_RELATIONS_TODO = "financial-relations-todo";

	static BasicCollectionRegistry instance ;
	
	public static BasicCollectionRegistry getInstance() {
		if( instance == null )
			initInstance() ;
		return instance;
	}
	
	public static void disposeInstance(){
		instance = null ;
	}
	
	ArrayList<IObjectCollection> collectionList = new ArrayList<IObjectCollection>() ;
	
	HashMap<String, IObjectCollection> nameMap = new HashMap<String, IObjectCollection>() ;
	
	HashMap<Integer, IObjectCollection> idMap = new HashMap<Integer, IObjectCollection>() ;
	
	@Override
	public List<IObjectCollection> getAllCollections() {
		return collectionList ;
	}

	@Override
	public IObjectCollection getCollection(int id) {
		return idMap.get(id);
	}

	@Override
	public IObjectCollection getCollectionByName(String name) {
		return nameMap.get(name);
	}
	
	@Override
	public void addCollection(IObjectCollection collection)
	{		
		int id = collectionList.size() ;
		collectionList.add(collection) ;
		collection.setId(id) ;
		idMap.put( id, collection ) ;
		nameMap.put( collection.getName(), collection) ;
	}
	
	public static void loadInstance(String path){
		
		File f = new File( path ) ;
		if(!f.exists())
			return ;
		
		ObjectInputStream ois;
		try {
			ois = new ObjectInputStream( new FileInputStream(f));
			Object readObject = ois.readObject();
			ois.close() ;
			instance =  (BasicCollectionRegistry) readObject ;			
		} catch (StreamCorruptedException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}		
	} ;

	public static void saveInstance(String path){
		
		File f = new File( path ) ;
		if(f.exists())
			f.delete() ;
		
		try {
			f.createNewFile() ;
			ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(f)) ;
			oos.writeObject( instance ) ;
			oos.close() ;
			
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}
	
	private static void initInstance() {
		
		String[] names = new String[]{
				
			COLLECTION_NAME_SIMPLE_TODO,
			COLLECTION_NAME_FINANCIAL_RELATIONS,
			COLLECTION_NAME_MONEY_COUNTER,
			COLLECTION_NAME_GENERAL_STORAGE,
			COLLECTION_NAME_FINANCIAL_RELATIONS_TODO,
			COLLECTION_NAME_MONEY_COUNTER_TODO,
			COLLECTION_NAME_GENERAL_STORAGE_TODO			
		} ;
		
		IMemberValueCalculator[] calcs = new IMemberValueCalculator[]{
				new LastValueCalculator(),//	COLLECTION_NAME_GENERAL_TODO,
				new CounterValueCalculator(),//	COLLECTION_NAME_FINANTIAL_RELATIONS,
				new CounterValueCalculator(),//	COLLECTION_NAME_MONEY_COUNTER,
				new LastValueCalculator(),//	COLLECTION_NAME_GENERAL_STORAGE,
				new CounterValueCalculator(),//	COLLECTION_NAME_FINANTIAL_RELATIONS_TODO,
				new CounterValueCalculator(),//	COLLECTION_NAME_MONEY_COUNTER_TODO,
				new LastValueCalculator()//	COLLECTION_NAME_GENERAL_STORAGE_TODO				
		} ;
		
		instance = new BasicCollectionRegistry() ;
		
		CollectionsContainer totalTodo = new CollectionsContainer(COLLECTION_NAME_GENERAL_TODO,instance) ;
		for( String name : names ){
			if(!name.endsWith("todo"))
				continue ;
			
			totalTodo.addChild(name) ;
		}
		
		instance.addCollection(totalTodo) ;
		
		int size = Math.min(names.length, calcs.length) ;
		for( int i = 0 ; i < size ; i++ ){
			String name = names[i] ;
			IMemberValueCalculator calc = calcs[i] ;
			BasicCollection collection = new BasicCollection( name, calc ) ;
			instance.addCollection(collection) ;
		}
		instance.getCollectionByName(COLLECTION_NAME_MONEY_COUNTER).addNewMember( new BasicCollectionMember<Object>("counter")) ;
		instance.getCollectionByName(COLLECTION_NAME_MONEY_COUNTER_TODO).addNewMember( new BasicCollectionMember<Object>("counter")) ;
	}

	public void clear() {
		for(IObjectCollection collection : collectionList){
			collection.getCompleteHistory().clear() ;
		}		
	}	
}
